package reportBuilder;

import gov.alaska.dnr.identity.DetailUserInfo;
import gov.alaska.dnr.identity.ImCommonLib;
import gov.alaska.dnr.identity.MemberInfoSourceManager;
import gov.alaska.dnr.util.alogger.LoggerCommonLib;
import gov.alaska.dnr.util.alogger.RemoteLogger;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import us.ak.state.dnr.service.database.DatabaseLite;

public class Gofor extends HttpServlet {

	/**
	 * I don't know why it wants it to have a serialVersionUID, but here it is.
	 */
	private static final long serialVersionUID = 238964067139347620L;
	
	/** The initialization flag. Indicates if the servlet has been initialized or not. */
	private boolean initialized = true;
	
	/** This is all stuff that is needed for the servlet itself*/
	public static String BANNER = "http://int.dnr.alaska.gov/shared/images/banners/gis75.jpg";
	/** This is the version and creation data of the Report Builder*/
	public static String VERSION = "1.0.0 (12/29/2009)";
	/** This is for passing error messages to the JavaServer login page.*/
	public static String S_EXTERNAL_MESSAGE = "dbrs.message.external";
	
	/* These are the data structures for the servlet*/
	/** Global Properties file */
	private static Properties props = new Properties();
	/** Application Properties file name. */
	public static final String PROPS_FILE_NAME = "/builder.properties";
	/** Identity Management Properties file name. */
	public static String IM_PROPS_FILE_NAME = "/im.properties";
	/** Database Service Properties file name. */
	public static String DB_PROPS_FILE_NAME = "/db.properties";
	
	/** Identity Management Source Manager. */
	private MemberInfoSourceManager imSourceMgr = null;
	private String userID;
	/** Internal message text (used for the logger) */
	private static String msg = "";
	/** List of system administrators */
	public String sysAdminGroup = new String("DNR GIS Web Application");
	/** This is a boolean flag to show whether the user is successfully logged in or not*/
	private boolean loggedIn = false;
	/** This is a boolean flag to show whether the user has a report that they are in the process of 
	 *  working on or not. */
	private boolean reportChosen = false;
	/** This is a boolean flag to show whether the report that the user is working on is a new report
	 *  or one that already exists and they are just editing. */
	private boolean newReport = false;
	
	/** Hashtable address: The request type. */
	public static final String HT_REQUEST_TYPE = "reqtype";
	/** Hashtable address: The URL of the requesting page. */
	private static final String HT_LINK_URL = "url";
	/** Hashtable address: The Form Button value. */
	public static final String HT_FORM_BUTTON = "SUBMIT";
	/** Hashtable address: The Section value. */
	public static final String HT_PAGE_SECTION = "SECTION";
	/** Hashtable address: The Purpose value. */
	public static final String HT_REQUEST_PURPOSE = "PURPOSE";
	/** Hashtable address: The Date value. */
	public static final String HT_REQUEST_DATA = "DATA";
	
	/** This is the object that stores all of the report data for the entire report*/ 
	private Report report_data = null;
	/** These are flags for if the data has been loaded correctly.*/
	private boolean driverFlag = false;
	private boolean fieldsFlag = false;
	private boolean parametersFlag = false;
	private boolean securityFlag = false;
	private boolean categoriesFlag = false;
	
	/** Miscellanious strings defined here*/
	protected static final String null_value = "null";
	protected static final String default_value = "default";
	private static final String genericSQLErrorMessage = "There was an SQL Exception thrown when trying ";
	/** The strings for dealing with Login.jsp, starting with the URL, then the request type*/
	private static final String LOGIN_URL = "Login.jsp";
	private static final String MISC_FORM = "FORM";
	/** The strings for dealing with ChooseReport.jsp and it's PURPOSEs*/
	private static final String MISC_FORM_URL = "ChooseReport.jsp";
	private static final String MISC_FORM_EDIT = "Edit";
	private static final String MISC_FORM_CREATE = "Create";
	private static final String MISC_FORM_ID_LIST = "ID list";
	/** The strings for dealing with ReportBuilder.jsp*/
	private static final String MISC_BUILDER_URL = "ReportBuilder.jsp";
	// The strings dealing with it's PURPOSEs
	private static final String MISC_BUILDER_ID = "report ID";
	private static final String MISC_BUILDER_SAVE ="save";
	private static final String MISC_BUILDER_LOAD ="load";
	private static final String MISC_BUILDER_COMMIT ="commit";
	private static final String MISC_BUILDER_SCRIPT ="getScript";
	private static final String MISC_BUILDER_CLOSE ="close";
	private static final String MISC_BUILDER_LOGOUT ="logout";
	// The strings dealing with it's SECTIONs
	private static final String MISC_BUILDER_DRIVER ="Driver Table";
	private static final String MISC_BUILDER_UI ="User Interface Data";
	private static final String MISC_BUILDER_FIELDS ="Fields Table";
	private static final String MISC_BUILDER_PARAMETERS ="Parameters Table";
	private static final String MISC_BUILDER_SECURITY ="Security Table";
	private static final String MISC_BUILDER_CATEGORIES ="Categories Table";
	private static final String MISC_BUILDER_DYNAMIC_FIELDS ="Field Names and Types";
	// The string for pulling it's DATA
	private static final String MISC_BUILDER_DATA =HT_REQUEST_DATA;
	   
	/* This is the block that sets the system environment as far as connecting to the database goes*/
	/** This is the connection to the database.*/
	private Connection myConn;
	/** This is the string "dbrs." */
	private String schema;
	/** This is the string "report_driver" */
	private String driver;
	/** This is the string "report_fields" */
	private String fields;
	/** This is the string "report_parameters" */
	private String parameters;
	/** This is the string "report_security" */
	private String security;
	/** This is the string "report_categories" */
	private String category;
	/** This is the string "category" */
	private String categories_names;
	/** This holds the Service name */
	private String dbService;
	/** This holds the Service User Name */
	private String dbUserName;
	/** This holds the Service Password */
	private String dbPass;
	  
	/** This is the statement 'select * from '*/
	private char[] get_all_from_table1 = new char[]{'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' '};
	/** This is the statement ' where report_id='*/
	private char[] get_all_from_table2 = new char[]{' ','w','h','e','r','e',' ','r','e','p','o','r','t','_','i','d','='};
	
	/* Logger information*/
	/** Logger object */
	private static RemoteLogger LOGGER;
	/** The Remote Logger URL (see properties) */
	private static String REMOTE_LOGGER_URL = "http://fox.dnr.state.ak.us/ALogger/LoggerServer";
	/** The Logger Level for this application, default=DEBUG (see properties) */
	private static String LOGGER_LEVEL = "DEBUG";
	/** The Logger Name for this application, default=DRB (see properties) */
	private static String LOGGER_NAME = "DRB";
	/** The OS file system separator */
	public static String FILE_SEPARATOR; 
	 /** Full OS Path to Context */
	 private static String ContextPath = null;
	
	/**
	 * This method initializes the servlet, getting the strings needed to get data from the database
	 * and making the servlet persistent in the server.
	 * @param config The servlet init. parameter
	 * @exception ServletException is thrown if there is problem initializing the servlet.
	 */
	public void init(ServletConfig config) throws ServletException
	{
		super.init(config);
		
		// Set the OS file seperator
		FILE_SEPARATOR = System.getProperty("file.separator");
	    String prop;
		
		try
		{
			InputStream is = getClass().getResourceAsStream(PROPS_FILE_NAME);
	        props.load(is);
	        is.close();
	        
	        try { // Grabs the full context path for use with the logger
				ContextPath = getServletContext().getRealPath(FILE_SEPARATOR);
			} catch (Exception e) {
				msg = "Error determining the servlet context. "+e;
				System.err.println(msg);
				this.initialized = false;
			} finally {
				if(is != null) is.close();
			}
			
			// get the administrator's group name...
			prop = props.getProperty("admin.group");
			if (prop != null) sysAdminGroup = prop;
			
			// Try to create a remote logger for server
	        prop = props.getProperty("REMOTE_LOGGER_URL");
	        if (prop != null) REMOTE_LOGGER_URL = prop;
	        prop = props.getProperty("LOGGER_LEVEL");
	        if (prop != null) LOGGER_LEVEL = prop;
	        prop = props.getProperty("LOGGER_NAME");
	        if (prop != null) LOGGER_NAME = prop;
	        
	        try 
	        {
	        	LOGGER = new RemoteLogger(
	        			LOGGER_NAME,
	        			RemoteLogger.getDistributedID(FILE_SEPARATOR,ContextPath),
	        			LoggerCommonLib.HTML_OUTPUT_FORMAT_TYPE, // html format
	        			REMOTE_LOGGER_URL,
	        			LoggerCommonLib.getLevel(LOGGER_LEVEL));
	        	logIt("init - Remote logger successfully created.",0);
	        } // end try
	        catch (Exception e) 
	        {
	          msg = "Unable to create logger: " + e;
	          System.err.println(msg);
	          this.initialized = false;
	        } // end catch
	        
	        Properties dbProps = new Properties();
	        InputStream is2 = null;
	        is2 = getClass().getResourceAsStream(DB_PROPS_FILE_NAME);
	        dbProps.load(is2);
	        is2.close();
	        
	        // Sets up all the relevant strings for getting data from the database
	        prop = dbProps.getProperty("database.dbSchema");
	        if(prop != null) schema = prop;
	        prop = dbProps.getProperty("database.table.driver");
	        if(prop != null) driver = prop;
	        prop = dbProps.getProperty("database.table.fields");
	        if(prop != null) fields = prop;
	        prop = dbProps.getProperty("database.table.parameters");
	        if(prop != null) parameters = prop;
	        prop = dbProps.getProperty("database.table.security");
	        if(prop != null) security = prop;
	        prop = dbProps.getProperty("database.table.category");
	        if(prop != null) category = prop;
	        prop = dbProps.getProperty("database.table.categories");
	        if(prop != null) categories_names = prop;
	        prop = dbProps.getProperty("DNRDEV-DBRSADMIN.SERVICE");
	        if(prop != null) dbService = prop;
	        prop = dbProps.getProperty("DNRDEV-DBRSADMIN.USER_NAME");
	        if(prop != null) dbUserName = prop;
	        prop = dbProps.getProperty("DNRDEV-DBRSADMIN.USER_PASS");
	        if(prop != null) dbPass = prop;
	        
	        
	        // Initialize Identity Management Source Manager...
	        Properties imProps = new Properties();
	        InputStream is3 = null;
       
	        try 
	        {
	        	is3 = getClass().getResourceAsStream(IM_PROPS_FILE_NAME);
	        	imProps.load(is3);
	        	// create manager...
	        	this.imSourceMgr = new MemberInfoSourceManager(ImCommonLib.properties2Sources(imProps));
	        } catch (Exception e) {
	        	logIt("Failed to load and create Identity Management Source Manager. "+e.getMessage(),2);
	        } finally {
	        	if (is3 != null)
	        	{
	        		try {
	        			is3.close();
	        		} catch (IOException e) {
	        			logIt("Failed to close the Identity Management . "+e.getMessage(),2);
	        		}
	        	}
	        }// end try catch finally loading im properties
		}
		catch(Exception e)
		{
			logIt("init - Error loading DRB servlet, init failed: " + e.getMessage(),4);
	        this.initialized = false;
		}
		
		// check initialization status...
	    if (this.initialized) logIt("init - Initialized DRB Servlet, version " + VERSION,1);
	    else logIt("init - failed to initialize DRB Servlet.",3);
	}// --------- end of init(config)
	
	/**
	 * Shutdown the servlet gracefully.  This is making sure that the connection to the server
	 * is closed and closing the Logger connection gently.
	 */
	public void destroty()
	{
		logIt("destroy - DRB Servlet services shutdown.",1);
		try {
			if(myConn != null && !myConn.isClosed())
				myConn.close();
		} catch (SQLException e) {
			// Not sure if I should put something here.
		}
		// close logger...
		if (LOGGER != null) LOGGER.close();
        // Call super destroy
        super.destroy();
	}// --------- end of destroy()
	
	/**
	 * Handle GET method requests. All requests are shunted to the doPost 
	 * method for processing.
	 * @param req The request to the servlet
	 * @param res The response from the servlet
	 * @exception IOException thrown if detected when handling the request
	 * @exception ServletException thrown if the request could not be handled
	 */
	public void doGet(HttpServletRequest request,
            HttpServletResponse response)
	throws ServletException, IOException
	{
		doPost(request, response);
	}
	
	/**
	 * Handle POST method requests. All requests are determined,
	 * processed or forwarded to the appropriate handling method.
	 * @param req The request to the servlet
	 * @param res The response from the servlet
	 * @exception IOException thrown if detected when handling the request
	 * @exception ServletException thrown if the request could not be handled
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException
	{
		if(this.initialized)
		{
			StringBuilder sb = new StringBuilder();
			HttpSession session = request.getSession(true);
			
			// if the user is logged in
			if(session != null)
			{
				Hashtable<String, String> reqTable = getFormFieldsHT(request);
				
				String strRequestType = (String)reqTable.get(HT_REQUEST_TYPE);
				
				// Which page is requesting or sending information?
				String url = (String)reqTable.get(HT_LINK_URL);
				// The requesting page is using a FORM Submit to send information.
				if(strRequestType.equalsIgnoreCase(MISC_FORM))
				{
					// The FORM request is from the Login page.
					if(url.equalsIgnoreCase(LOGIN_URL)){
						login(request, response);
					}
					// The FORM request is from the ChooseReport page.
					else if(url.equalsIgnoreCase(MISC_FORM_URL) && loggedIn && dbConnection(request))
					{
						String purpose = (String)reqTable.get(HT_REQUEST_PURPOSE);
						if(purpose.equals(MISC_FORM_ID_LIST))
						{
							try {
								dynamicIDList(response, session, sb);
							} catch (SQLException e) {
								logIt("dynamicIDList - "+genericSQLErrorMessage+"to get the ID list: "+e.getMessage(),3);
								// Set content-type and get PrintWriter
								response.setContentType("text/plain");
								PrintWriter out = response.getWriter();
							     
								out.println();
								out.close();
							}
						}
						else if(purpose.equalsIgnoreCase(MISC_FORM_EDIT))
						{
							edit(request, response, sb);
						}
						else if(purpose.equalsIgnoreCase(MISC_FORM_CREATE))
						{
							create(request, response, sb);
						}
						else
						{
							logIt("Page "+MISC_FORM_URL+" sent in an unknown PURPOSE: "+(String)reqTable.get(HT_REQUEST_PURPOSE),3);
							forwardToPage(request, response, LOGIN_URL);
						}
					}
				}// end request is FORM type
				else if(url.equalsIgnoreCase(MISC_BUILDER_URL) && loggedIn && dbConnection(request) && reportChosen)
				{
					String purpose = (String)reqTable.get(HT_REQUEST_PURPOSE);
					String section = (String)reqTable.get(HT_PAGE_SECTION);
					
					if(purpose.equalsIgnoreCase(MISC_BUILDER_ID))
					{
						response.setContentType("application/x-www-form-urlencoded");
					    PrintWriter out = response.getWriter();
					    out.print(URLEncoder.encode(report_data.driver[0],"UTF-8"));
						out.close();
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_LOAD))
					{
						JSONArray output= new JSONArray();
						JSONObject temp_obj;
						if(section.equalsIgnoreCase(MISC_BUILDER_DRIVER))
						{
							output = new JSONArray();
							for(int i = 0;i < 12;i++)
							{
								output.put(report_data.driver[i]);
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_UI))
						{
							//report_data.printUILinks();
							output = new JSONArray();
							output.put(report_data.driver[0]);
							for(int i = 12;i < 16;i++)
							{
								output.put(report_data.driver[i]);
							}
							for(int i = 0;i < report_data.ui_trail.length;i++)
							{
								output.put(report_data.ui_trail[i]);
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_FIELDS))
						{
							output = new JSONArray();
							temp_obj = new JSONObject();
							output.put(report_data.driver[0]);
							for(int i = 0;i < report_data.fields.size();i++)
							{
								temp_obj = new JSONObject(report_data.fields.get(i),JSONObject.getNames(report_data.fields.get(i)));
								output.put(temp_obj);
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_PARAMETERS))
						{
							output = new JSONArray();
							temp_obj = new JSONObject();
							output.put(report_data.driver[0]);
							for(int i = 0;i < report_data.parameters.size();i++)
							{
								temp_obj = new JSONObject(report_data.parameters.get(i),JSONObject.getNames(report_data.parameters.get(i)));
								output.put(temp_obj);
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_SECURITY))
						{
							output = new JSONArray();
							output.put(report_data.driver[0]);
							for(int i = 0;i < report_data.security_parameters.size();i++)
							{
								output.put(report_data.security_parameters.get(i));
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_CATEGORIES))
						{
							try {
								categoryList(request,response,sb);
							} catch (SQLException e) {
								logIt("dynamicIDList - "+genericSQLErrorMessage+"to get the ID list: "+e.getMessage(),3);
							}
						}
						else if(section.equalsIgnoreCase(MISC_BUILDER_DYNAMIC_FIELDS))//TODO this is where it is sent to the client
						{
							String string = null;
							if(report_data.driver[7] != null && report_data.driver[7].length() > 0 && 
									report_data.driver[8] != null && report_data.driver[8].length() > 0 && request.getParameter(MISC_BUILDER_DATA) == null)
							{
								string = fieldsList(report_data.driver[7].toUpperCase(),report_data.driver[8].toUpperCase(),sb);
							}
							if(request.getParameter(HT_REQUEST_DATA) != null)
							{
								String[] value = request.getParameterValues(MISC_BUILDER_DATA);
								value = value[0].split("\",\"");
								string = fieldsList(value[0].substring(2).toUpperCase(),value[1].substring(0, (value[1].length()-2)).toUpperCase(),sb);
							}
							output = new JSONArray();
							if(string == null)
								output.put(string);
							else
							{
								for(int i = 0;i< report_data.valid_fields.size();i++)
								{
									output.put(report_data.valid_fields.get(i));
								}
							}
						}
						
						response.setContentType("application/json");
					    PrintWriter out = response.getWriter();
					    out.print(output);
						out.close();
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_SAVE))
					{
						if(request.getParameter("SECTION").equalsIgnoreCase("Driver Table"))
						{
							try {
								saveDriverTable(request);
							} catch (JSONException e) {
								logIt("A JSON Exception was thrown by saveDriverTable(): "+e.getMessage(),3);
							}
						}
						else if(request.getParameter("SECTION").equalsIgnoreCase("User Interface Data"))
						{
							try {
								saveUI(request);
							} catch (JSONException e) {
								logIt("A JSON Exception was thrown by saveUI(): "+e.getMessage(),3);
							}
						}
						else if(request.getParameter("SECTION").equalsIgnoreCase("Fields Table"))
						{
							try {
								saveFieldsTable(request);
							} catch (JSONException e) {
								logIt("A JSON Exception was thrown by saveFieldsTable(): "+e.getMessage(),3);
							}
						}
						else if(request.getParameter("SECTION").equalsIgnoreCase("Parameters Table"))
						{
							try {
								saveParametersTable(request);
							} catch (JSONException e) {
								logIt("A JSON Exception was thrown by saveParametersTable(): "+e.getMessage(),3);
							}
						}
						else if(request.getParameter("SECTION").equalsIgnoreCase("Security Table"))
						{
							try {
								saveSecurityTable(request);
							} catch (JSONException e) {
								logIt("A JSON Exception was thrown by saveSecurityTable(): "+e.getMessage(),3);
							}
						}
						else if(request.getParameter("SECTION").equalsIgnoreCase("Categories Table"))
						{
							if(request.getParameter(HT_REQUEST_DATA) != null)
							{
								report_data.CATEGORY = Integer.parseInt(request.getParameter(HT_REQUEST_DATA));
							}
						}
						response.setContentType("text/text");
					    PrintWriter out = response.getWriter();
					    out.print('A'+'C'+'K');
						out.close();
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_COMMIT))
					{
						commitDataStructure(sb);
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_SCRIPT))
					{
						generateScript(sb,response);
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_CLOSE))
					{
						if (loggedIn && reportChosen) {
							closeDataBase();
							reportChosen = false;
							sb.setLength(0);
							sb.append(new char[] { 'A', 'C', 'K' });
							response.setContentType("text/plain");
							PrintWriter out = response.getWriter();
							out.println(sb.toString());
							out.close();
						}
					}
					else if(purpose.equalsIgnoreCase(MISC_BUILDER_LOGOUT))
					{
						closeDataBase();
						session.removeAttribute(ImCommonLib.S_MEMBER_OBJECT);
						logIt(userID+" has successfully logged out.",1);
						session.invalidate();
						session = null;
						loggedIn = false;
						reportChosen = false;
						this.forwardToPage(request, response, "./Login.jsp");
					}
				}// end request from ReportBuilder page
				else
				{
					//logIt("The request was not of type FORM and did not come from "+MISC_BUILDER_URL+", thus was invalid.  Redirecting to login page.",3);
					forwardToPage(request, response, LOGIN_URL);
				}// end unknown request from ReportBuilder page.
			}// end non-null session
			else
			{
				logIt("The session is closed. Redirecting to the login page.",3);
				forwardToPage(request, response, LOGIN_URL);
			}// end session is null
		}// end servlet initiated
		else {
			logIt("DRB Report Builder servlet was not initialized correctly.",3);
			forwardToPage(request, response, LOGIN_URL);
		}// else servlet not initiated
	}// --------- end of doPost
	
	/**
	 * This is a method to get a dynaimically generated list of available report's IDs, used 
	 * exclusively on the ChooseReport page.
	 * @param response
	 * @param session
	 * @param sb This is used to build the output string.
	 * @throws IOException This is thrown only if there are problems with sending the response out
	 * @throws SQLException This is thrown only if there are problems with the database connection
	 */
	private void dynamicIDList(HttpServletResponse response, HttpSession session,
			StringBuilder sb) throws IOException, SQLException {
		// select distinct(report_id) from dbrs.report_river
		sb.append(new char[]{'s','e','l','e','c','t',' ','d','i','s','t','i','n','c','t',
				'(','r','e','p','o','r','t','_','i','d',')',' ','f','r','o','m',' ','d','b','r','s','.',
				'r','e','p','o','r','t','_','d','r','i','v','e','r'});
		Statement myStatement = myConn.createStatement();
		ResultSet myResults = myStatement.executeQuery(sb.toString());
		
		ArrayList<String> myList = new ArrayList<String>();
		
		if (myResults.isBeforeFirst()) {
			while (myResults.next()) // returns false when there is nothing left or nothing there
			{
				myList.add(myResults.getString(1));
			}
		}
		try {
			myStatement.close();
		} catch (Exception e) {}
		
		sb.setLength(0);
		sb.append(new String("<option value='null' selected='selected'>None</option>"));
		for(int i = 0;i < myList.size();i++)
		{
			sb.append(new String("<option value='"));
			sb.append(myList.get(i));
			sb.append("'>");
			sb.append(myList.get(i));
			sb.append(new String("</option>"));
		}
		
		// Set content-type and get PrintWriter
		response.setContentType("text/plain");
		PrintWriter out = response.getWriter();
	     
		out.println(sb.toString());
		out.close();
	}

	/**
	 * The purpose of this method is to get data from the Oracle database so the report that the data<br/>
	 * represents can be edited.
	 * @param request
	 * @param response
	 * @param sb
	 * @throws IOException 
	 */
	private void edit(HttpServletRequest request, HttpServletResponse response,
			StringBuilder sb) throws IOException
			{
		report_data = new Report();
		reportChosen = true;
		newReport = false;
		
		String report_id = request.getParameter(HT_FORM_BUTTON);
		report_id = '\''+report_id+'\'';
		
		try {
			Statement dbRetrevalStatement = myConn.createStatement();
			ArrayList<String> myList = new ArrayList<String>();
			
			try {		
				// This is getting data from teh report_driver table
				getDriverData(sb, report_id, dbRetrevalStatement, myList);
				driverFlag = true;
			} catch (SQLException e) {
				logIt("edit - "+genericSQLErrorMessage+"\""+sb.toString()+"\": "+e.getMessage(),3);
			}
			
			// This is getting data from the report_fields table
			try {
				getFieldsData(sb, report_id, dbRetrevalStatement, myList);
				fieldsFlag = true;
			} catch (SQLException e) {
				logIt("edit - "+genericSQLErrorMessage+"\""+sb.toString()+"\": "+e.getMessage(),3);
			}
			
			// This is getting data from the report_parameters table
			try {
				getParametersData(sb, report_id, dbRetrevalStatement, myList);
				parametersFlag = true;
			} catch (SQLException e) {
				logIt("edit - "+genericSQLErrorMessage+"\""+sb.toString()+"\": "+e.getMessage(),2);
			}
			
			// This is getting data from the report_security table
			try {
				getSecurityData(sb, report_id, dbRetrevalStatement, myList);
				securityFlag = true;
			} catch (SQLException e) {
				logIt("edit - "+genericSQLErrorMessage+"\""+sb.toString()+"\": "+e.getMessage(),3);
			}
			
			// This is the start of the getting data from the report_categories table
			try {
				getCategoriesTable(sb, report_id, dbRetrevalStatement, myList);
				categoriesFlag = true;
			} catch (SQLException e) {
				logIt("edit - "+genericSQLErrorMessage+"\""+sb.toString()+"\": "+e.getMessage(),3);
			}
			// This is the end of the getting data from the report_categories table
			
			try {
				dbRetrevalStatement.close();
			} catch (SQLException e) {
				logIt("edit - There was an Exception thrown when closing dbRetrevalStatement: "+e.getMessage(),3);
			}
		} catch (SQLException e) {
			logIt("edit - There was an SQL Exception thrown when trying to create dbRetrevalStatement: "+e.getMessage(),3);
		}
		
		this.forwardToPage(request, response, MISC_BUILDER_URL);
	}// --------- end of edit()
	
	private void getDriverData(StringBuilder sb, String report_id,
			Statement dbRetrevalStatement, ArrayList<String> myList) throws SQLException 
	{		
		sb.setLength(0);
		sb.append(get_all_from_table1);
		sb.append(schema);
		sb.append(driver);
		sb.append(get_all_from_table2);
		sb.append(report_id);
		ResultSet myResults = dbRetrevalStatement.executeQuery(sb.toString());
	
		
		if (myResults.isBeforeFirst()) {
			myResults.next();
			for (int i = 1; i <= 17; i++) {
				myList.add(myResults.getString(i));
			}
		}
		else
		{
			throw new SQLException("empty Results set");
		}
		
		myResults.close();
		 
		for(int i = 0;i < myList.size();i++)
		{
			if(i < 17)
				report_data.driver[i] = myList.get(i);
		}
		String[] ui_trail_temp;
		if(isNotNull(report_data.driver[16]) && report_data.driver[16].contains(" <span style=\"font-size: 9.5pt;\">&gt;</span> "))
		{
			ui_trail_temp = report_data.driver[16].split(" <span style=\"font-size: 9.5pt;\">&gt;</span> ");	
		}
		else
		{
			ui_trail_temp = new String[] {report_data.driver[16]};
		}
		
		report_data.ui_trail = new String[ui_trail_temp.length][2];

		for(int i = 0;i<ui_trail_temp.length;i++)
		{
			// Makes the first cut, making sure that the cut is inside of the string, instead of returning a '-1' result
			int firstCut = ui_trail_temp[i].indexOf("href=\"")+6; // 6 characters to remove from the front of the string
			if(firstCut == 0)
				firstCut = ui_trail_temp[i].indexOf("href=&quot;")+11; // 11 characters to remove from the front of the string
			// Makes the second cut, making sure that the cut is inside of the string, instead of returning a '-1' result
			int secondCut = ui_trail_temp[i].indexOf("\"", firstCut+1);
			if(secondCut == -1)
				secondCut = ui_trail_temp[i].indexOf("&quot;", firstCut+1);
			// Storing the part of the string that was cut out, the URL
			report_data.ui_trail[i][0] = ui_trail_temp[i].substring(firstCut, secondCut);
			
			// Makes the first cut, making sure that the cut is inside of the string, instead of returning a '-1' result
			firstCut = ui_trail_temp[i].indexOf("\">")+2; // 2 characters to remove from the front of the string.
			if(firstCut == 1)
				firstCut = ui_trail_temp[i].indexOf("&quot;>")+7; // 7 characters to remove from the front of the string.
			// Making a second cut and storing the part of the string that was cut out, the text of the link.  No need to 
			// make sure that the .indexOf() doesn't return '-1'
			report_data.ui_trail[i][1] = ui_trail_temp[i].substring(firstCut, ui_trail_temp[i].indexOf("<", firstCut+1));
		}
	}// --------- end of getDriverData()

	/**
	 * This method is to get data from the DBRSAdmin.REPORT_FIELDS table and put it into the Report data structure.
	 * @param sb
	 * @param report_id
	 * @param dbRetrevalStatement
	 * @param myList
	 * @throws SQLException
	 */
	private void getFieldsData(StringBuilder sb, String report_id,
			Statement dbRetrevalStatement, ArrayList<String> myList)
			throws SQLException 
	{
		ResultSet myResults;
		sb.setLength(0);
		sb.append(get_all_from_table1);
		sb.append(schema);
		sb.append(fields);
		sb.append(get_all_from_table2);
		sb.append(report_id);
		myResults = dbRetrevalStatement.executeQuery(sb.toString());
		
		myList.clear();
		
		
		if (myResults.isBeforeFirst()) {
			while (myResults.next()) {
				for (int i = 1; i <= 12; i++) {
					myList.add(myResults.getString(i));
				}
			}
		}
		else
		{
			throw new SQLException("empty Results set");
		}		
		
		report_data.fields.clear();
		
		try {
			ArrayList<Field> temp_list = new ArrayList<Field>();
			for(int i = 0;i < myList.size();i++)
			{
				if(myList.get(i).equalsIgnoreCase(report_id.substring(1, report_id.length()-1)))
				{
					i++;
					int n = 0;
					report_data.currentField.field[n++] = myList.get(i++);//FIELD_NAME
					report_data.currentField.field[n++] = myList.get(i++);//FIELD_DISPLAY_NAME
					report_data.currentField.field[n++] = myList.get(i++);//DESCRIPTION
					report_data.currentField.ORDERING = new Integer(myList.get(i++));
					report_data.currentField.field[n++] = myList.get(i++);//SORTABLE
					report_data.currentField.field[n++] = myList.get(i++);//DEFAULT_SELECTED
					report_data.currentField.field[n++] = myList.get(i++);//DEFAULT_SORT_ORDER
					report_data.currentField.field[n++] = myList.get(i++);//DATA_TYPE
					report_data.currentField.field[n++] = myList.get(i++);//FUNCTION
					report_data.currentField.field[n++] = myList.get(i++);//VALUE_INFO
					report_data.currentField.field[n++] = myList.get(i);//DISPLAY
					
					temp_list.add(report_data.currentField);
					report_data.currentField = new Field();
				}
			}
			
			// for each field in the temp list
			for(int i = 0;i<temp_list.size();i++)
			{
				// look through each field in the temp list
				for(int n = 0;n < temp_list.size();n++)
				{
					// if that field's number in the order is equal to the current spot in number line
					if(temp_list.get(n).ORDERING == (i+1))
					{
						// toss it into it's propper spot in the fields list, makeing it an ordered list.
						report_data.fields.add(temp_list.get(n));
						temp_list.get(n).printField();
					}
				}
			}
			
		} catch (Exception e) {
			logIt("getFieldsData - There was an Exception thrown when putting a field into the ArrayList: "+e.getMessage(),3);
		}
	}// --------- end of getFieldsData()
	
	/**
	 * This method is to get data from the DBRSAdmin.REPORT_PARAMETERS table and put it into the Report data structure.
	 * @param sb
	 * @param report_id
	 * @param dbRetrevalStatement
	 * @param myList
	 * @throws SQLException
	 */
	private void getParametersData(StringBuilder sb, String report_id,
			Statement dbRetrevalStatement, ArrayList<String> myList)
			throws SQLException {
		ResultSet myResults;
		sb.setLength(0);
		sb.append(get_all_from_table1);
		sb.append(schema);
		sb.append(parameters);
		sb.append(get_all_from_table2);
		sb.append(report_id);
		myResults = dbRetrevalStatement.executeQuery(sb.toString());
		
		myList.clear();
		if (myResults.isBeforeFirst()) {
			while (myResults.next()) {
				for (int i = 1; i <= 16; i++) {
					myList.add(myResults.getString(i));
				}
			}
			myResults.close();
		}
		else
		{
			throw new SQLException("empty Results set");
		}
		
		report_data.parameters.clear();
		try {
			for(int i = 0;i < myList.size();i++)
			{
				if(myList.get(i).equalsIgnoreCase(report_id.substring(1, report_id.length()-1)))
				{// if this i is the report_id
					i++;
					int n = 0;
					report_data.currentParameter.parameter[n++] = myList.get(i++);//PARAMETER_NAME
					report_data.currentParameter.parameter[n++] = myList.get(i++);//PARAMETER_DISPLAY_NAME
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DESCRIPTION
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DATA_TYPE
					report_data.currentParameter.ORDERING = new Integer(myList.get(i++));
					report_data.currentParameter.parameter[n++] = myList.get(i++);//REQUIRED
					report_data.currentParameter.parameter[n++] = myList.get(i++);//ACTUAL_VALUES
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DISPLAY_VALUES
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DS_SCHEMA_NAME
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DS_DATASOURCE
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DS_FIELD_NAMES
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DS_WHERE_CLAUSE
					report_data.currentParameter.parameter[n++] = myList.get(i++);//DS_ORDER_BY_CLAUSE
					
					if (myList.get(i)!= null) {//CONSTRAINING_PARAMETER_NAME
						report_data.currentParameter.parameter[n++] = myList.get(i++).toUpperCase();
					}
					else
					{
						report_data.currentParameter.parameter[n++] = null_value.toUpperCase();
						i++;
					}
					
					report_data.currentParameter.parameter[n++] = myList.get(i);//VALIDATOR_NAME
					
					report_data.parameters.add(report_data.currentParameter);
					report_data.currentParameter = new Parameter();
				}
			}
		} catch (Exception e) {
			logIt("getParametersData - There was an Exception thrown when putting a parameter into the ArrayList: "+e.getMessage(),3);
		}
	}// --------- end of getParametersData()
	
	/**
	 * This method is to get data from the DBRSAdmin.REPORT_SECURITY table and put it into the Report data structure.
	 * @param sb
	 * @param report_id
	 * @param dbRetrevalStatement
	 * @param myList
	 * @throws SQLException
	 */
	private void getSecurityData(StringBuilder sb, String report_id,
			Statement dbRetrevalStatement, ArrayList<String> myList)
			throws SQLException {
		ResultSet myResults;
		sb.setLength(0);
		sb.append(get_all_from_table1);
		sb.append(schema);
		sb.append(security);
		sb.append(get_all_from_table2);
		sb.append(report_id);
		myResults = dbRetrevalStatement.executeQuery(sb.toString());
		
		myList.clear();
		if (myResults.isBeforeFirst()) {
			while (myResults.next()) {
				myList.add(myResults.getString(1));
				myList.add(myResults.getString(2));
				myList.add(myResults.getString(3));
			}
			myResults.close();
		}
		else
		{
			throw new SQLException("empty Results set");
		}
		
		String[] temp_holding;
		report_data.security_parameters.clear();
		try {
			for(int i = 0;i < myList.size();i++)
			{
				if(myList.size() >0 && i%3 == 0 && myList.get(i).equalsIgnoreCase(report_id.substring(1, report_id.length()-1)))
				{
					temp_holding = new String[2];
					temp_holding[0]= myList.get(i+1);
					temp_holding[1] = myList.get(i+2);
					report_data.security_parameters.add(temp_holding);
				}
			}
		} catch (Exception e) {
			logIt("getSecurityData - There was an Exception thrown when putting a row into the ArrayList: "+e.getMessage(),3);
		}
	}// --------- end of getSecurityData()
	
	/**
	 * This method is to get data from the DBRSAdmin.REPORT_CATEGORIES table and put it into the Report data structure.
	 * @param sb
	 * @param report_id
	 * @param dbRetrevalStatement
	 * @param myList
	 * @throws SQLException
	 */
	private void getCategoriesTable(StringBuilder sb, String report_id,
			Statement dbRetrevalStatement, ArrayList<String> myList)
			throws SQLException {
		ResultSet myResults;
		sb.setLength(0);
		sb.append(get_all_from_table1);
		sb.append(schema);
		sb.append(category);
		sb.append(get_all_from_table2);
		sb.append(report_id);
		myResults = dbRetrevalStatement.executeQuery(sb.toString());
		
		myList.clear();
		
		if (myResults.isBeforeFirst()) {
			myResults.next();
			for (int i = 1;i <= 2;i++) {
				myList.add(myResults.getString(i));
			}
		}
		else
		{
			throw new SQLException("empty Results set");
		}
		myResults.close();
		
		if(myList.size() >0 && myList.get(0).equalsIgnoreCase(report_id.substring(1, report_id.length()-1)))
		{
			report_data.CATEGORY = Integer.parseInt(myList.get(1));
		}	
	}// --------- end of getCategoriesData()
	
	private void create(HttpServletRequest request,	HttpServletResponse response, StringBuilder stringBuilder) throws IOException {
		report_data = new Report();
		reportChosen = true;
		newReport = true;
		
		String report_id = request.getParameter("SUBMIT");
		report_id = '\''+report_id+'\'';
		report_data.driver[0] = report_id.substring(1, report_id.length()-1);
		forwardToPage(request, response, MISC_BUILDER_URL);
	}// --------- end of create()
	
	private void categoryList(HttpServletRequest request,
			HttpServletResponse response, StringBuilder sb) throws SQLException, IOException {
		// select distinct(report_id) from dbrs.report_river
		sb.append(new char[]{'s','e','l','e','c','t',' ','d','i','s','t','i','n','c','t',
				'(','c','a','t','e','g','o','r','y','_','i','d',')',',',
				'c','a','t','e','g','o','r','y','_','n','a','m','e',' ','f','r','o','m',' ','d','b','r','s','.'});
		sb.append(categories_names);
		ArrayList<Category> categories = new ArrayList<Category>();
		
		if(myConn != null)
		{
			Statement myStatement = myConn.createStatement();
			ResultSet myResults = myStatement.executeQuery(sb.toString());
			
			
			
			boolean alreadyIn;
			while(myResults.next()) // returns false when there is nothing left or nothing there
			{
				alreadyIn = false;
				for(int i = 0;i<categories.size();i++)
				{
					if(categories.get(i).id > myResults.getInt("category_id"))
					{
						categories.add(i,new Category(myResults.getInt("category_id"), myResults.getString("category_name")));
						alreadyIn = true;
						break;
					}
				}
				if(!alreadyIn)
					categories.add(new Category(myResults.getInt("category_id"), myResults.getString("category_name")));
			}
			
			try {
				myStatement.close();
			} catch (Exception e) {}
		}	

		JSONArray output = new JSONArray();
		output.put(report_data.driver[0]);
		for(int i = 0;i < categories.size();i++)
		{
			output.put(categories.get(i).name);
		}
		output.put(report_data.CATEGORY);
		// Set content-type and get PrintWriter
	    response.setContentType("application/json");
	    PrintWriter out = response.getWriter();
	    out.println(output);
	    out.close();
	}
	
	/**
	 * This method gets the valid column names and their corresponding types from the 
	 * Oracle database metadata table.
	 * @param schema
	 * @param datasource
	 * @param sb
	 * @return "success" if completed successfully, or null if not
	 */
	private String fieldsList(String schema, String datasource, StringBuilder sb) {
		ResultSet myResults;
		Statement dbRetrevalStatement = null;
		boolean lock = true;
		
		while (lock) {
			try {
				dbRetrevalStatement = myConn.createStatement();
				lock = false;
			} catch (Exception e) {
				logIt("fieldsList - The myConn failed createStatement(). "+e.getMessage(),3);
				return null;
			}
		}
		sb.setLength(0);
		sb.append(new char[] {'s','e','l','e','c','t',' ','c','o','l','u','m','n','_','n','a','m','e',',',' ','d','a','t','a','_','t','y','p','e',' ','f','r','o','m',' ','a','l','l','_','t','a','b','_','c','o','l','u','m','n','s',' ','w','h','e','r','e',' ','o','w','n','e','r',' ','=',' ','\''});
		sb.append(schema);
		sb.append(new char[] {'\'',' ','a','n','d',' ','t','a','b','l','e','_','n','a','m','e',' ','=',' ','\''});
		sb.append(datasource);
		sb.append(new char[] {'\''});
		try {
			myResults = dbRetrevalStatement.executeQuery(sb.toString());
		} catch (Exception e) {
			logIt("fieldsList - The query \""+sb.toString()+"\" failed: "+e.getMessage(),3);
			return null;
		}
		ArrayList<String[]> myList = new ArrayList<String[]>();
		
		try {
			if (myResults.isBeforeFirst()) {
				while (myResults.next()) {
					myList.add(new String[] {myResults.getString(1),myResults.getString(2)});
				}
			}
		} catch (Exception e) {
			logIt("fieldsList - The query \""+sb.toString()+"\"s results had an error: "+e.getMessage(),3);
			return null;
		}
		
		try {
			myResults.close();
		} catch (Exception e) {
			logIt("fieldsList - There was an error thrown when trying to close myResults: "+e.getMessage(),3);
		}
		sb.setLength(0);
		report_data.driver[7] = schema;
		report_data.driver[8] = datasource;
		report_data.valid_fields = myList;
		myList = null;
		sb.append(new char[] {'s','u','c','c','e','s','s'});
		return sb.toString();
	}
	
	/**
	 * This method is called when the request sends data about the Driver table back from the client with<br/>
	 * a request to save it.
	 * @param request
	 * @throws JSONException
	 */
	private void saveDriverTable(HttpServletRequest request) throws JSONException {
		JSONObject recieved_data;
		if(request.getParameter(HT_REQUEST_DATA) != null && request.getParameter(HT_REQUEST_DATA) != "")
		{
			recieved_data = new JSONObject(request.getParameter(HT_REQUEST_DATA));
			
			String name = new String("reportName");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[1] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[1] = null_value;
			}
			
			name = new String("reportDesc");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[2] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[2] = null_value;
			}
			
			name = new String("driverComments");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[3] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[3] = null_value;
			}
			
			name = new String("driverActive");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[4] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[4] = null_value;
			}
			
			name = new String("byPassed");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[5] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[5] = null_value;
			}
			
			name = new String("reportSchema");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[7] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[7] = null_value;
			}
			
			name = new String("reportDS");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[8] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[8] = null_value;
			}
			
			name = new String("mapName");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[9] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[9] = null_value;
			}
			
			name = new String("mapUID");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[10] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[10] = null_value;
			}
			
			name = new String("coord_system_name");
			
		}
		else
			logIt("the data from the driver accordion fold did not get here.",2);
	}// --------- end of saveDriverTable()
	
	/**
	 * This method is called when the request sends data about the User Interface section of the Driver<br/>
	 * table back from the client with a request to save it.
	 * @param request
	 * @throws JSONException
	 */
	private void saveUI(HttpServletRequest request) throws JSONException {
		JSONObject recieved_data,data2;
		JSONArray recieved_array;
		String[] temp;
		if(request.getParameter(HT_REQUEST_DATA) != null && request.getParameter(HT_REQUEST_DATA) != "")
		{
			recieved_data = new JSONObject(request.getParameter(HT_REQUEST_DATA));
			
			String name = new String("interface_page_title");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[12] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[12] = default_value;
			}
			
			name = new String("interface_header_title");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[13] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[13] = default_value;
			}
			
			name = new String("interface_subHeader_title");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[14] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[14] = default_value;
			}
			
			name = new String("interface_image_address");
			if(isNotNull(recieved_data.getString(name)))
			{
				report_data.driver[15] = recieved_data.getString(name);
			}
			else
			{
				report_data.driver[15] = default_value;
			}
			if(recieved_data.getJSONArray("links_list") != null)
			{
				recieved_array = recieved_data.getJSONArray("links_list");
				
				if (recieved_array.length() >= 1) {
					this.report_data.ui_trail = new String[(Integer) recieved_array.length() - 1][2];
					for (int i = 1; i < recieved_array.length(); i++) {
						temp = new String[2];
						data2 = recieved_array.getJSONObject(i);

						name = new String("link_text");
						if (isNotNull(data2.getString(name))) {
							temp[1] = data2.getString(name);
						} else {
							temp[1] = "Natural Resources";
						}

						name = new String("link_address");
						if (isNotNull(data2.getString(name))) {
							temp[0] = data2.getString(name);
						} else {
							temp[0] = "http://dnr.alaska.gov/";
						}

						report_data.ui_trail[i-1][0] = temp[0];
						report_data.ui_trail[i-1][1] = temp[1];
					}
					//report_data.printUILinks();
				}
			}
			else
				logIt("No list of links were in the request to be put into the UI data structure.",3);
		}
		else
			logIt("the data from the UI accordion fold did not get here.",2);
	}// --------- end of saveUI()
	
	/**
	 * This method is called when the request sends data about the Fields table back from the client with<br/>
	 * a request to save it.
	 * @param request
	 * @throws JSONException
	 */
	private void saveFieldsTable(HttpServletRequest request) throws JSONException {
		JSONObject recieved_data;
		JSONArray recieved_array;
		String[] temp;
		if(request.getParameter(HT_REQUEST_DATA) != null && request.getParameter(HT_REQUEST_DATA) != "")
		{
			recieved_array = new JSONArray(request.getParameter(HT_REQUEST_DATA));
			report_data.fields.clear();
			for(int i = 1;i<recieved_array.length();i++)
			{
				temp = new String[10];
				int n = 0;
				recieved_data = recieved_array.getJSONObject(i);
				
				String name = new String("field_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[n] = recieved_data.getString(name);
					n++;
				}
				else
				{
					temp[n] = null_value;
					n++;
				}
				
				name = new String("field_display_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[n] = recieved_data.getString(name);
					n++;
				}
				else
				{
					temp[n] = null_value;
					n++;
				}
				
				name = new String("description");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[n] = recieved_data.getString(name);
					n++;
				}
				else
				{
					temp[n] = null_value;
					n++;
				}
				temp[n++] = recieved_data.getString("field_sortable");
				temp[n++] = recieved_data.getString("default_selected");
				temp[n++] = recieved_data.getString("field_sort_order");
				temp[n++] = recieved_data.getString("data_type");
				
				name = new String("field_function");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[n] = recieved_data.getString(name);
					n++;
				}
				else
				{
					temp[n] = null_value;
					n++;
				}
				
				name = new String("value_info");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[n] = recieved_data.getString(name);
					n++;
				}
				else
				{
					temp[n] = null_value;
					n++;
				}
				temp[n++] = recieved_data.getString("display");
				
				
				report_data.fields.add(new Field((i),temp));
				/*for(int x = 0;x < report_data.fields.size();x++)
					report_data.fields.get(x).printField();*/
			}
			
		}
		else
			logIt("the data from the fields accordion fold did not get here.",2);
	}// --------- end of saveFieldsTable()
	
	/**
	 * This method is called when the request sends data about the Parameterss table back from the client<br/> 
	 * with a request to save it.
	 * @param request
	 * @throws JSONException
	 */
	private void saveParametersTable(HttpServletRequest request) throws JSONException {
		JSONObject recieved_data;
		JSONArray recieved_array;
		String[] temp;
		int order;
		if(request.getParameter(HT_REQUEST_DATA) != null && request.getParameter(HT_REQUEST_DATA) != "")
		{
			Parameter tempParameter;
			recieved_array = new JSONArray(request.getParameter(HT_REQUEST_DATA));
			report_data.parameters.clear();
			for(int i = 1;i<recieved_array.length();i++)
			{
				temp = new String[14];
				recieved_data = recieved_array.getJSONObject(i);
				
				String name = new String("parameter_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[0] = recieved_data.getString(name);
				}
				else
				{
					temp[0] = null_value;
				}
				
				name = new String("parameter_display_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[1] = recieved_data.getString(name);
				}
				else
				{
					temp[1] = null_value;
				}
				
				name = new String("parameter_description");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[2] = recieved_data.getString(name);
				}
				else
				{
					temp[2] = null_value;
				}
				
				name = new String("data_type");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[3] = recieved_data.getString(name);
				}
				else
				{
					temp[3] = null_value;
				}
				
				name = new String("parameter_required");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[4] = recieved_data.getString(name);
				}
				else
				{
					temp[4] = "F";
				}
				
				name = new String("actual_values");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[5] = recieved_data.getString(name);
				}
				else
				{
					temp[5] = null_value;
				}
				
				name = new String("display_values");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[6] = recieved_data.getString(name);
				}
				else
				{
					temp[6] = null_value;
				}
				
				name = new String("ds_schema");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[7] = recieved_data.getString(name);
				}
				else
				{
					temp[7] = null_value;
				}
				
				name = new String("ds_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[8] = recieved_data.getString(name);
				}
				else
				{
					temp[8] = null_value;
				}
				
				name = new String("ds_field_names");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[9] = recieved_data.getString(name);
				}
				else
				{
					temp[9] = null_value;

				}
				
				name = new String("where_clause");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[10] = recieved_data.getString(name);

				}
				else
				{
					temp[10] = null_value;

				}
				
				name = new String("order_by_clause");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[11] = recieved_data.getString(name);

				}
				else
				{
					temp[11] = null_value;

				}
				
				name = new String("constraining_parameter_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[12] = recieved_data.getString(name);

				}
				else
				{
					temp[12] = null_value;

				}
				
				name = new String("validator_name");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[13] = recieved_data.getString(name);

				}
				else
				{
					temp[13] = null_value;

				}
				
				name = new String("parameter_number");
				if(isNotNull(recieved_data.getString(name)))
					order = Integer.parseInt(recieved_data.getString(name));
				else
					order = -1;
				
				tempParameter = new Parameter(order,temp);
				//tempParameter.printParameter();
				report_data.parameters.add(tempParameter);
			}
		}
		else
			logIt("the data from the parameters accordion fold did not get here.",2);
	}// --------- end of saveParametersTable() 
	
	/**
	 * This method is called when the request sends data about the Security table back from the client with<br/>
	 * a request to save it.
	 * @param request
	 * @throws JSONException
	 */
	private void saveSecurityTable(HttpServletRequest request) throws JSONException {
		JSONObject recieved_data;
		JSONArray recieved_array;
		String[] temp;
		if(request.getParameter(HT_REQUEST_DATA) != null && request.getParameter(HT_REQUEST_DATA) != "")
		{
			recieved_array = new JSONArray(request.getParameter(HT_REQUEST_DATA));
			report_data.security_parameters.clear();
			for(int i = 1;i<recieved_array.length();i++)
			{
				temp = new String[2];
				recieved_data = recieved_array.getJSONObject(i);
				
				String name = new String("security_parameters"); 
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[1] = recieved_data.getString(name);
				}
				else
				{
					temp[1] = null_value;
				}
				
				name = new String("security_restriction");
				if(isNotNull(recieved_data.getString(name)))
				{
					temp[0] = recieved_data.getString(name);
				}
				else
				{
					temp[0] = "PUBLIC";
				}
				
				report_data.security_parameters.add(temp);
			}
		}
		else
			logIt("the data from the security accordion fold did not get here.",2);
	}// --------- end of saveSecurityTable()
	
	/**
	 * This method commits everything in the Report data structure to the Oracle database.
	 * @param sb
	 * @throws SQLException
	 */
	private void commitDataStructure(StringBuilder sb)// throws SQLException 
	{
		Statement dbCommitStatement= null;
		
		// If the report currently being saved is not a new report...
		if (!newReport) {
			// then clear the tables of the old data so the new data could be written.
			clearTheTables(sb, dbCommitStatement);
		}
		String table = driver;
		sb.setLength(0);
		if (newReport || driverFlag) {
			try {
				dbCommitStatement = insertDriver(sb, table);
			} catch (SQLException e) {
				logIt(genericSQLErrorMessage+sb.toString()+": " + e.getMessage(),3);
			}
		}
		table = fields;
		
		if (newReport || fieldsFlag) {
			for (int n = 0; n < report_data.fields.size(); n++) {
				sb.setLength(0);
				try {
					dbCommitStatement = insertField(sb, table, n);
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage + sb.toString() + ": "
							+ e.getMessage(), 3);
				}
			}
		}
		table = parameters;
		
		if (newReport || parametersFlag) {
			for (int n = 0; n < report_data.parameters.size(); n++) {
				sb.setLength(0);
				try {
					dbCommitStatement = insertParameter(sb, table, n);
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage + sb.toString() + ": "
							+ e.getMessage(), 3);
				}
			}
		}
		table = security;
		
		if (newReport || securityFlag) {
			for (int i = 0; i < report_data.security_parameters.size(); i++) {
				sb.setLength(0);
				try {
					dbCommitStatement = insertSecurity(sb, table, i);
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage + sb.toString() + ": "
							+ e.getMessage(), 3);
				}
			}
		}
		table = category;
		
		sb.setLength(0);
		if (newReport || categoriesFlag) {
			try {
				dbCommitStatement = insertCategories(sb, table);
			} catch (SQLException e) {
				logIt(genericSQLErrorMessage + sb.toString() + ": "
						+ e.getMessage(), 3);
			}
		}
		
		try {
			commit(dbCommitStatement);
		} catch (SQLException e) {
			logIt(genericSQLErrorMessage+sb.toString()+": " + e.getMessage(),3);
		}
		
		if(newReport)
			newReport = false;
	}// --------- end of commitDataStructure() 
	
	/**
	 * This method inserts everything in the driver section of the Report data structure into the Oracle database.
	 * @param sb
	 * @param table
	 * @return
	 * @throws SQLException
	 */
	private Statement insertDriver(StringBuilder sb,
			String table) throws SQLException {
		Statement dbCommitStatement;
		sb.setLength(0);
		sb.append(new char[]{'i','n','s','e','r','t',' ','i','n','t','o',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','v','a','l','u','e','s',' ','('});
		//report_data.printDriver();
		report_data.driver[16] = "";
		if(report_data.ui_trail.length > 0)
			report_data.driver[16] += "<a href=\""+parseForOracle(report_data.ui_trail[0][0])+"\">"+parseForOracle(report_data.ui_trail[0][1])+"</a>";
		for(int i = 1;i < this.report_data.ui_trail.length;i++)
		{
			report_data.driver[16] += " <span style=\"font-size: 9.5pt;\">'||chr(38)||'gt;</span> <a href=\""+
					parseForOracle(report_data.ui_trail[i][0])+"\">"+parseForOracle(report_data.ui_trail[i][1])+"</a>";
		}
		for(int i = 0;i < report_data.driver.length-1;i++)
		{
			if(isNotNull(report_data.driver[i]) && i != 6)
				sb.append("'"+report_data.driver[i]+"'");
			else if(i == 6)
				sb.append(default_value);
			else
				sb.append(null_value);
			sb.append(new char[]{','});
		}
		if(isNotNull(report_data.driver[report_data.driver.length-1]))
			sb.append('\''+report_data.driver[report_data.driver.length-1]+'\'');
		else
			sb.append(null_value);
		sb.append(new char[]{')'});		
		dbCommitStatement = myConn.createStatement();
		logIt("Report Builder ready to send the statement: "+sb.toString(),1);
		if(sb.length() != 0)
			dbCommitStatement.execute(sb.toString());
		
		commit(dbCommitStatement);
		return dbCommitStatement;
	}// --------- end of insertDriver()
	
	/**
	 * This method builds the line of SQL to insert one of the Field type
	 * @param sb
	 * @param table
	 * @param n
	 * @return
	 * @throws SQLException
	 */
	private Statement insertField(StringBuilder sb, String table, int n)
			throws SQLException 
	{
		Statement dbCommitStatement;
		sb.setLength(0);
		sb.append(new char[]{'i','n','s','e','r','t',' ','i','n','t','o',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','v','a','l','u','e','s',' ','('});
		sb.append('\''+report_data.driver[0]+'\''+',');
		for(int i = 0;i < report_data.fields.get(n).field.length-1;i++)
		{
			if(i == 3)
			{
				sb.append(report_data.fields.get(n).ORDERING);
				sb.append(',');
			}

			if(isNotNull(report_data.fields.get(n).field[i]))
				sb.append('\''+parseForOracle(report_data.fields.get(n).field[i])+'\'');
			else if(i == 5 || i == 6 || i == 8 || i == 11)
				sb.append(default_value);
			else
				sb.append(null_value);
			sb.append(new char[]{','});
		}
		if(isNotNull(report_data.fields.get(n).field[report_data.fields.get(n).field.length-1]))
			sb.append('\''+report_data.fields.get(n).field[report_data.fields.get(n).field.length-1]+'\'');
		else
			sb.append(null_value);
		sb.append(new char[]{')'});
				
		dbCommitStatement = myConn.createStatement();
		logIt("Report Builder ready to send the statement: "+sb.toString(),1);
		if(sb.length() != 0)
			dbCommitStatement.execute(sb.toString());
		return dbCommitStatement;
	}// --------- end of insertField()
	
	/**
	 * This method puts the n-th parameter in the parameters ArrayList into the database.
	 * @param sb
	 * @param table The String 'report_parameters'
	 * @param n
	 * @return
	 * @throws SQLException
	 */
	private Statement insertParameter(StringBuilder sb, String table, int n) throws SQLException {
		Statement dbCommitStatement;
		sb.setLength(0);
		sb.append(new char[]{'i','n','s','e','r','t',' ','i','n','t','o',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','v','a','l','u','e','s',' ','('});
		sb.append('\''+report_data.driver[0]+'\''+',');
		for(int i = 0;i < report_data.parameters.get(n).parameter.length-1;i++)
		{
			if(i == 4)
			{
				sb.append(report_data.parameters.get(n).ORDERING);
				sb.append(',');
			}

			if(isNotNull(report_data.parameters.get(n).parameter[i]))
				sb.append('\''+parseForOracle(report_data.parameters.get(n).parameter[i])+'\'');
			else
				sb.append(null_value);
			sb.append(new char[]{','});
		}
		
		if(isNotNull(report_data.parameters.get(n).parameter[report_data.parameters.get(n).parameter.length-1]))
			sb.append('\''+report_data.parameters.get(n).parameter[report_data.parameters.get(n).parameter.length-1]+'\'');
		else
			sb.append(null_value);
		sb.append(new char[]{')'});
				
		dbCommitStatement = myConn.createStatement();
		logIt("Report Buidler ready to send the statement: "+sb.toString(),1);
		if(sb.length() != 0)
			dbCommitStatement.execute(sb.toString());
		return dbCommitStatement;
	}// --------- end of insertParameter() 

	/**
	 * This method inserts everything in the security section of the Report data structure into the Oracle database.
	 * @param sb
	 * @param table
	 * @param i 
	 * @return
	 * @throws SQLException 
	 */
	private Statement insertSecurity(StringBuilder sb, String table, int n) throws SQLException {
		Statement dbCommitStatement;
		sb.setLength(0);
		sb.append(new char[]{'i','n','s','e','r','t',' ','i','n','t','o',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','v','a','l','u','e','s',' ','('});
		sb.append('\''+report_data.driver[0]+'\''+',');
		if(isNotNull(report_data.security_parameters.get(n)[0]))
		{
			sb.append('\'');
			sb.append(report_data.security_parameters.get(n)[0]);
			sb.append(new char[]{'\'',','});
		}
		else
			sb.append(new char[] {'\'','p','u','b','l','i','c','\'',','});
		
		if(isNotNull(report_data.security_parameters.get(n)[1]))
		{
			sb.append('\'');
			sb.append(report_data.security_parameters.get(n)[1]);
			sb.append(new char[]{'\''});
		}
		else
		{
			sb.append(null_value);
		}
			
		sb.append(new char[]{')'});
					
		dbCommitStatement = myConn.createStatement();
		logIt("Report Builder ready to send the statement: "+sb.toString(),1);
		if(sb.length() != 0)
			dbCommitStatement.execute(sb.toString());
		return dbCommitStatement;
	}// --------- end of insertSecurity() 

	/**
	 * This method inserts everything in the category section of the Report data structure into the Oracle database.
	 * @param sb
	 * @param table
	 * @return
	 * @throws SQLException 
	 */
	private Statement insertCategories(StringBuilder sb, String table) throws SQLException {
		Statement dbCommitStatement;
		sb.append(new char[]{'i','n','s','e','r','t',' ','i','n','t','o',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','v','a','l','u','e','s',' ','('});
		sb.append('\'');
		sb.append(report_data.driver[0]);
		sb.append(new char[] {'\'',','});
		sb.append(report_data.CATEGORY);
		sb.append(new char[]{')'});
		dbCommitStatement = myConn.createStatement();
		logIt("Report Builder ready to send the statement: "+sb.toString(),1);
		dbCommitStatement.execute(sb.toString());
		
		try {
			commit(dbCommitStatement);
		} catch (Exception e) {e.printStackTrace();}
		return dbCommitStatement;
	}// --------- end of insertCategories() 
	
	/**
	* This method is to clear the tables so they can have the new data inserted.  If
	* data has been loaded correctly, as shown by the appropriate flag being true,
	* then the statement to clear out the relevant data is created and sent to the 
	* database.  If the data wasn't loaded correctly initially, then the data isn't
	* cleared out to make way for the new data.
	* @param sb
	* @param dbCommitStatement
	*/
	private void clearTheTables(StringBuilder sb, Statement dbCommitStatement) {
		try {
			dbCommitStatement = myConn.createStatement();
			String temp ;
			
			sb.setLength(0);
			if (fieldsFlag) {
				deleteString(sb, fields);
				temp = sb.toString();
				try {
					dbCommitStatement.executeUpdate(sb.toString());
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage+temp+": "+e.getMessage(),3);
				}
			}
			
			sb.setLength(0);
			if (parametersFlag) {
				deleteString(sb, parameters);
				temp = sb.toString();
				try {
					dbCommitStatement.executeUpdate(sb.toString());
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage+temp+": "+e.getMessage(),3);
				}
			}
			
			sb.setLength(0);
			if (securityFlag) {
				deleteString(sb, security);
				temp = sb.toString();
				try {
					dbCommitStatement.executeUpdate(sb.toString());
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage+temp+": "+e.getMessage(),3);
				}
			}
			
			sb.setLength(0);
			if (categoriesFlag) {
				deleteString(sb, category);
				temp = sb.toString();
				try {
					dbCommitStatement.executeUpdate(sb.toString());
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage+temp+": "+e.getMessage(),3);
				}
			}
			
			sb.setLength(0);
			if (driverFlag) {
				deleteString(sb, driver);
				temp = sb.toString();
				try {
					dbCommitStatement.executeUpdate(sb.toString());
				} catch (SQLException e) {
					logIt(genericSQLErrorMessage+temp+": "+e.getMessage(),3);
				}
			}
			
			commit(dbCommitStatement);
		} catch (SQLException e) {
			logIt("There was a general SQL Exception thrown when trying to clear the tables: "+e.getMessage(),3);
		}
	}// --------- end of clearTheTables()
	
	/**
	* This method builds a string "DELETE FROM <schema name>.<table name> WHERE REPORT_ID = '<the id of the report>'"
	* @param sb		The StringBuilder object that will hold the string
	* @param table	The name of the table
	*/
	private void deleteString(StringBuilder sb,String table)
	{
		sb.append(new char[]{'D','E','L','E','T','E',' ','F','R','O','M',' '});
		sb.append(schema);
		sb.append(table);
		sb.append(new char[]{' ','W','H','E','R','E',' ','R','E','P','O','R','T','_','I','D',' ','=',' ','\''});
		sb.append(report_data.driver[0]);
		sb.append(new char[]{'\''});
	}// --------- end of deleteString()
	
	/**
	 * This method sends the 'commit' statement to the database.
	 * @param dbCommitStatement
	 * @throws SQLException
	 */
	private void commit(Statement dbCommitStatement) throws SQLException 
	{
		dbCommitStatement = myConn.createStatement();
		dbCommitStatement.executeUpdate(MISC_BUILDER_COMMIT);
		dbCommitStatement.close();
	}// --------- end of commit() 
	
	/**
	* This method generates the script to create the report and sends it as an attachment.  This should make
	* it download-able like the PDFs and Excel documents, but it doesn't.  Instead, it is read like any other
	* text.
	* @param response 
	* @return 
	* @throws IOException 
	*/
	private boolean generateScript(StringBuilder sb, HttpServletResponse response) throws IOException
	{
		Script script = new Script(report_data, schema, driver, fields, parameters, security, category);
		response.setContentType("text/plain");
		sb.setLength(0);
		sb.append(new char[]{'a','t','t','a','c','h','m','e','n','t',';','f','i','l','e','n','a','m','e','=','R','E','P','O','R','T','_','I','D'});
		sb.append(report_data.driver[0]);
		sb.append(new char[] {'.','s','q','l'});
		   
		response.setHeader("Content-disposition",sb.toString());
		sb.setLength(0);
		String temp = script.getString(sb);
		ServletOutputStream out = response.getOutputStream();
		ByteArrayInputStream bis = new ByteArrayInputStream(temp.getBytes());
		BufferedOutputStream bos = new BufferedOutputStream(out);
		   
		byte[] buff = new byte[2048];
	    int bytesRead;

	    // Simple read/write loop.
	    while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
	    	bos.write(buff, 0, bytesRead);
	    } // end while a stream to write.
	    // clean up
	    try {
	    	bis.close();
	    	} // end try.
	    catch(Exception eee) {
	    	logIt("generateScript - Error closing Input Stream. " + eee,3);
	    } // end catch.
	    try {
	    	bos.close();
	    } // end try.
	    catch(Exception eee) {
	    	logIt("generateScript - Error closing Output Stream. " + eee,3);
	    } // end catch.
	    return true;
	}// --------- end of generateScript() 

	/**
	 * Closes the connection so when the user navigates away from the editor page, there is no hanging open
	 * 		connections.
	 * @throws SQLException
	 */
	private void closeDataBase(){
		try {
			myConn.close();
			myConn = null;
			report_data.close();
			report_data = null;
			logIt("Successfully closed the data base connections.",1);
		} catch (SQLException e) 
		{
			logIt("closeDataBase - There was a SQL Exception thrown: "+e.getMessage(),3);
		}
	}// --------- end of closeDataBase()
	
	/**
	 * This method takes in a string, and parses it so that Oracle will accept it.
	 * @param oldString The original String.
	 * @return The String, now cleared of all characters that Oracle doesn't like.
	 */
	private String parseForOracle(String oldString)
	{
		StringBuilder newString = new StringBuilder();
		if(isNotNull(oldString))
		{
			for(int i = 0; i<oldString.length();i++)
			{
				switch(oldString.charAt(i))
				{
				case '&':
					newString.append(new char[] {'\'','|','|','c','h','r','(','3','8',')','|','|','\''});
					break;
				/*case '"':
					newString.append(new char[] {'\'','|','|','c','h','r','(','3','8',')','|','|','\'','q','u','o','t',';'});
					break;*/
				case '\'':
					newString.append(new char[] {'\'','|','|','c','h','r','(','3','9',')','|','|','\''});
					break;
				case '%':
					newString.append(new char[] {'\'','|','|','c','h','r','(','3','7',')','|','|','\''});
					break;
				default:
					newString.append(oldString.charAt(i));
				break;
				}
			}
			return newString.toString();
		}
		else return null_value;
	}// --------- end of parseForOracle()
	
	private boolean isNotNull(String input)
	{
		if(input == null || input.equalsIgnoreCase(null_value) || input.equalsIgnoreCase("'null'") || input.length() == 0)
			return false;
		else return true;
	}
	
	/**
	 * Read in the form fields the user submitted, and store them
	 * in a Hashtable. For the Hashtable keys, use the string
	 * constants that we have defined for use as Form Field names.
	 * They begin with the HT_ prefix.
	 * @param req The request to the servlet
	 * @return Hashtable Contains all HTML parameters sent in the request
	 */
	private Hashtable<String, String> getFormFieldsHT(HttpServletRequest req) 
	{
		Hashtable<String, String> ht = new Hashtable<String, String>(5);
		String param = null;
      
		// Get request type
		param = req.getParameter(HT_REQUEST_TYPE);
      
		if(param != null) 
		{
			ht.put(HT_REQUEST_TYPE, param);
		}
		else
			ht.put(HT_REQUEST_TYPE, "NONE");
      
		// Get LINK request URL
		param = req.getParameter(HT_LINK_URL);
		if(param != null)
			ht.put(HT_LINK_URL, param);
		else
			ht.put(HT_LINK_URL, "NONE");
		
		// Get FORM  request Button
		param = req.getParameter(HT_FORM_BUTTON);
		if(param != null)
			ht.put(HT_FORM_BUTTON, param);
		else
			ht.put(HT_FORM_BUTTON, "NONE");
	
		// Get SECTION data
		param = req.getParameter(HT_PAGE_SECTION);
		if(param != null)
			ht.put(HT_PAGE_SECTION, param);
		else
			ht.put(HT_PAGE_SECTION, "NONE");
		
		// Get PURPOSE data
		param = req.getParameter(HT_REQUEST_PURPOSE);
		if(param != null)
			ht.put(HT_REQUEST_PURPOSE, param);
		else
			ht.put(HT_REQUEST_PURPOSE, "NONE");
      
		return ht;
	}// --------- end of getFormFieldsHT()
	
	/**
	 * This method gets the user's ID and password from the FORM request, stores them
	 * in a hash table, and passes them into a DetailUserInfo class, which checks them
	 * against the user data in the LDAP system.
	 * @param request
	 * @param response - Used to forward the potential user to the Login page if the ID or password are incorrect.
	 * @throws IOException
	 */
	private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String thePage = null;
		// Create a new session to carry params
		HttpSession session = request.getSession(true);
		if(session != null) 
		{
			Hashtable<String,String> ht = getFormFieldsHT(request);
			
			String strRequestType = (String) ht.get(Gofor.HT_REQUEST_TYPE);
			if (strRequestType.equalsIgnoreCase("form")) {
				String strFormButton = (String) ht.get(Gofor.HT_FORM_BUTTON);
				if (strFormButton.equalsIgnoreCase("Log In")) {
					// Get user input
					String uid = request.getParameter("FF_USER_IDENTIFIER");
					String pass = request.getParameter("FF_USER_PASSWORD");

					if (uid != null && uid.length() > 0) {
						if (pass != null && pass.length() > 0) {
							// Create a DetailUserInfo object
							try {
								// Sanitize user input
								uid = uid.replace(" ", "");
								uid = uid.replace("'", "");
								pass = pass.replace(" ", "");
								pass = pass.replace("'", "");

								DetailUserInfo d = imSourceMgr.getDetailUser(
										uid, pass);
								userID = d.getMemberIdentifier();

								if (d != null) {
									session.setAttribute(ImCommonLib.S_MEMBER_OBJECT, d);
									loggedIn = true;
									dbConnection(request);
									thePage = MISC_FORM_URL;
								}
							} // end try
							catch (Exception e) {
								//e.printStackTrace();
								msg = "Unable to log in " + uid + " because: "
										+ e.getMessage();
								session.setAttribute(S_EXTERNAL_MESSAGE, msg);
								thePage = LOGIN_URL;
							} // end catch
						} // end if a password specified
						else {
							msg = "You must provide a User Password.";
							session.setAttribute(S_EXTERNAL_MESSAGE, msg);
							thePage = LOGIN_URL;
						} // end else no password specified
					} else {
						msg = "You must provide a User Identifier.";
						session.setAttribute(S_EXTERNAL_MESSAGE, msg);
						thePage = LOGIN_URL;
					} // end else no user id specified
					// forward...
					forwardToPage(request, response, thePage);
				}
			}
		}
		else 
		{
			logIt("Service - Session is null, forwarded to index page.",2);
			forwardToPage(request, response, LOGIN_URL);
		} // end else invalid session
	}// --------- end of login()
	
	/**
	 * This method checks to see if the network connection is up and if it isn't but
	 * should be, then it tries to reconnect.
	 * @param request
	 * @return true if connected, false if not connected
	 */
	private boolean dbConnection(HttpServletRequest request) {
		StringBuilder d = new StringBuilder();
		d.append(new char[]{'m','y','C','o','n','n','e','c','t','i','o','n'});
		HttpSession session = request.getSession();
		myConn = (Connection) session.getAttribute(d.toString()); 

		// if the connection is closed and the user is still logged in, reconnect.
		try {
			if((myConn == null || myConn.isClosed())&& loggedIn)
			{
				if (dbService != null && dbUserName != null && dbPass != null) {
					DatabaseLite mainConnection = new DatabaseLite(dbService,
							dbUserName, dbPass);
					myConn = mainConnection.getDedicatedConnection(false);
					session.setAttribute(d.toString(), myConn);
					mainConnection.close();
				}
			}
			return true;
		} catch (SQLException e) {
			logIt("dbConnection - The OR was ignored in the enclosed 'if' statement. "+e.getMessage(),3);
			return false;
		} catch (Exception e) {
			logIt("dbConnection - The mainConnection threw an error, meaning that the myConn connection was corrupted somehow. Setting myConn to null. "+e.getMessage(),3);
			myConn = null;
			session.setAttribute(d.toString(), myConn);
			return false;
		}
	}// --------- end of dbConnection()

	/**
	 * This forwards the client to another page.
	 * @param request
	 * @param response
	 * @param thePage	The relative URL of the page to be forwarded to.
	 * @throws IOException
	 */
	private void forwardToPage(HttpServletRequest request,
			HttpServletResponse response, String thePage) throws IOException {
		try {
			getServletConfig().getServletContext().getRequestDispatcher("/"+thePage).forward(request,response);
		} catch (Exception e) {
			String msg = "forwardToPage - Error forwarding to page \""+thePage+"\": "+e.getMessage();
			logIt(msg,3);
		}
	}// --------- end of forwardToPage()
	
	/**
	 * Log a given message to the specified logger if a valid logger,
	 *  else send to System.xxx.println().
	 * @param msg The message to print to logger
	 * @param level The level at which this message is associated with
	 */
	private void logIt(String msg, int level) 
	{
		// Prepend identifier
		msg = "[DRB Servlet] " + msg;
		
		// Check the logger
		if (LOGGER != null) 
		{
			if (level == 0) LOGGER.debug(msg);
			else if (level == 1) LOGGER.info(msg);
			else if (level == 2) LOGGER.warn(msg);
			else if (level == 3) LOGGER.error(msg);
			else if (level == 4) LOGGER.fatal(msg);
			else LOGGER.debug(msg);
		} // end if valid logger
		else 
		{
			if (level < 3 && level != 9) 
				System.out.println(msg);
			else 
				System.err.println(msg);
		} // end else not a valid logger
	} // end logIt method
}// --------- end of logIt()
